<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>短剧数据分析 - 词云图与热力图</title>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
    <!-- 使用正确的wordcloud扩展 -->
    <script src="https://cdn.jsdelivr.net/npm/echarts-wordcloud@2.0.0/dist/echarts-wordcloud.min.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
        }
        body {
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            color: #333;
            line-height: 1.6;
            padding: 20px;
            min-height: 100vh;
        }
        .container {
            max-width: 1400px;
            margin: 0 auto;
        }
        header {
            background: linear-gradient(90deg, #4b6cb7 0%, #182848 100%);
            color: white;
            padding: 30px 40px;
            text-align: center;
            border-radius: 15px 15px 0 0;
            margin-bottom: 20px;
        }
        h1 {
            font-size: 2.5rem;
            margin-bottom: 10px;
            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
        }
        .subtitle {
            font-size: 1.2rem;
            opacity: 0.9;
            font-weight: 300;
        }
        .dashboard {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
            margin-bottom: 20px;
        }
        .chart-container {
            background: white;
            border-radius: 15px;
            padding: 25px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
            height: 600px;
        }
        .chart-title {
            font-size: 1.5rem;
            color: #2c3e50;
            margin-bottom: 20px;
            text-align: center;
            font-weight: 600;
        }
        .stats-panel {
            background: white;
            border-radius: 15px;
            padding: 25px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
            margin-bottom: 20px;
        }
        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 20px;
            margin-top: 20px;
        }
        .stat-card {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            border-radius: 10px;
            text-align: center;
        }
        .stat-number {
            font-size: 2rem;
            font-weight: bold;
            margin-bottom: 5px;
        }
        .stat-label {
            font-size: 0.9rem;
            opacity: 0.9;
        }
        .controls {
            display: flex;
            gap: 15px;
            margin-bottom: 20px;
            flex-wrap: wrap;
        }
        .control-btn {
            background: #4b6cb7;
            color: white;
            border: none;
            padding: 12px 25px;
            border-radius: 8px;
            cursor: pointer;
            font-size: 1rem;
            font-weight: 600;
            transition: all 0.3s ease;
        }
        .control-btn:hover {
            background: #3a5795;
            transform: translateY(-2px);
        }
        .control-btn.active {
            background: #2c3e50;
        }
        .legend {
            display: flex;
            justify-content: center;
            flex-wrap: wrap;
            gap: 15px;
            margin-top: 15px;
        }
        .legend-item {
            display: flex;
            align-items: center;
            gap: 5px;
            font-size: 0.9rem;
        }
        .legend-color {
            width: 15px;
            height: 15px;
            border-radius: 3px;
        }
        .error-message {
            color: #e74c3c;
            background: #fadbd8;
            padding: 10px;
            border-radius: 5px;
            margin: 10px 0;
            display: none;
        }
        footer {
            text-align: center;
            padding: 20px;
            color: #7f8c8d;
            font-size: 0.9rem;
            margin-top: 30px;
        }
        @media (max-width: 1200px) {
            .dashboard {
                grid-template-columns: 1fr;
            }
            .chart-container {
                height: 500px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>短剧数据分析平台</h1>
            <p class="subtitle">基于日榜、周榜、月榜的热门标签词云与平台题材关系分析</p>
        </header>

        <div class="stats-panel">
            <h2>数据概览</h2>
            <div class="stats-grid">
                <div class="stat-card">
                    <div class="stat-number">88</div>
                    <div class="stat-label">总剧集数量</div>
                </div>
                <div class="stat-card">
                    <div class="stat-number">32</div>
                    <div class="stat-label">独特题材标签</div>
                </div>
                <div class="stat-card">
                    <div class="stat-number">15</div>
                    <div class="stat-label">平台方数量</div>
                </div>
                <div class="stat-card">
                    <div class="stat-number">4273.7w</div>
                    <div class="stat-label">最高热力值</div>
                </div>
            </div>
        </div>

        <div id="errorMessage" class="error-message"></div>

        <div class="controls">
            <button class="control-btn active" data-type="all">全部数据</button>
            <button class="control-btn" data-type="daily">日榜数据</button>
            <button class="control-btn" data-type="weekly">周榜数据</button>
            <button class="control-btn" data-type="monthly">月榜数据</button>
        </div>

        <div class="dashboard">
            <div class="chart-container">
                <div class="chart-title">热门题材标签词云图</div>
                <div id="wordCloudChart" style="width: 100%; height: 500px;"></div>
                <div class="legend">
                    <div class="legend-item">
                        <div class="legend-color" style="background: #c23531;"></div>
                        <span>高热度标签</span>
                    </div>
                    <div class="legend-item">
                        <div class="legend-color" style="background: #2f4554;"></div>
                        <span>中热度标签</span>
                    </div>
                    <div class="legend-item">
                        <div class="legend-color" style="background: #61a0a8;"></div>
                        <span>一般热度标签</span>
                    </div>
                </div>
            </div>

            <div class="chart-container">
                <div class="chart-title">平台与热门题材关系热力图</div>
                <div id="heatMapChart" style="width: 100%; height: 500px;"></div>
                <div class="legend">
                    <div class="legend-item">
                        <div class="legend-color" style="background: #c23531;"></div>
                        <span>高频出现</span>
                    </div>
                    <div class="legend-item">
                        <div class="legend-color" style="background: #fc8d59;"></div>
                        <span>中频出现</span>
                    </div>
                    <div class="legend-item">
                        <div class="legend-color" style="background: #fee090;"></div>
                        <span>低频出现</span>
                    </div>
                    <div class="legend-item">
                        <div class="legend-color" style="background: #e0f3f8;"></div>
                        <span>无数据</span>
                    </div>
                </div>
            </div>
        </div>

        <footer>
            <p>数据来源：短剧日榜、周榜、月榜统计 | 生成时间：2025年11月</p>
        </footer>
    </div>

    <script>
        // 显示错误信息
        function showError(message) {
            const errorDiv = document.getElementById('errorMessage');
            errorDiv.textContent = message;
            errorDiv.style.display = 'block';
        }

        // 隐藏错误信息
        function hideError() {
            document.getElementById('errorMessage').style.display = 'none';
        }

        // 检查ECharts和wordcloud扩展是否加载成功
        function checkDependencies() {
            if (typeof echarts === 'undefined') {
                showError('错误: ECharts库未正确加载，请检查网络连接');
                return false;
            }
            
            // 检查wordcloud扩展是否可用
            if (typeof echarts.registerMap === 'undefined') {
                showError('警告: WordCloud扩展可能未正确加载，但将尝试使用基础功能');
            }
            
            return true;
        }

        // 初始化ECharts实例
        let wordCloudChart, heatMapChart;

        try {
            wordCloudChart = echarts.init(document.getElementById('wordCloudChart'));
            heatMapChart = echarts.init(document.getElementById('heatMapChart'));
        } catch (error) {
            showError('图表初始化失败: ' + error.message);
        }

        // 数据处理函数
        function processData(dataType) {
            // 基础数据 - 基于您提供的短剧数据
            const allData = {
                daily: [
                    { name: '现代言情', value: 12, heat: 262.7 },
                    { name: '都市日常', value: 18, heat: 262.7 },
                    { name: '逆袭', value: 10, heat: 161.2 },
                    { name: '打脸虐渣', value: 4, heat: 98.2 },
                    { name: '无敌神医', value: 2, heat: 235.1 },
                    { name: '悬疑推理', value: 3, heat: 124.2 },
                    { name: '古装', value: 2, heat: 62 },
                    { name: '职场', value: 2, heat: 72.4 },
                    { name: '女性成长', value: 3, heat: 77.2 },
                    { name: '家庭伦理', value: 4, heat: 80.1 },
                    { name: '萌宝', value: 1, heat: 58.3 },
                    { name: '总裁', value: 2, heat: 83.1 },
                    { name: '都市修仙', value: 1, heat: 86.6 },
                    { name: '年代', value: 2, heat: 94.2 },
                    { name: '亲情', value: 2, heat: 68.2 },
                    { name: '古风权谋', value: 1, heat: 44.8 },
                    { name: '破镜重圆', value: 1, heat: 62 },
                    { name: '传承觉醒', value: 1, heat: 106.4 },
                    { name: '强者回归', value: 2, heat: 98.2 }
                ],
                weekly: [
                    { name: '逆袭', value: 12, heat: 1296.1 },
                    { name: '现代言情', value: 10, heat: 1296.1 },
                    { name: '都市日常', value: 14, heat: 1296.1 },
                    { name: '奇幻爱情', value: 4, heat: 1026.6 },
                    { name: '打脸虐渣', value: 3, heat: 792.3 },
                    { name: '无敌神医', value: 1, heat: 1296.1 },
                    { name: '悬疑推理', value: 4, heat: 470.5 },
                    { name: '职场', value: 2, heat: 556.6 },
                    { name: '女性成长', value: 2, heat: 556.6 },
                    { name: '家庭伦理', value: 4, heat: 469.2 },
                    { name: '现言甜宠', value: 1, heat: 556.6 },
                    { name: '异能', value: 1, heat: 514.6 },
                    { name: '虐恋', value: 3, heat: 503.1 },
                    { name: '亲情', value: 2, heat: 461.3 },
                    { name: '破镜重圆', value: 1, heat: 444.8 },
                    { name: '总裁', value: 2, heat: 356 },
                    { name: '古装', value: 2, heat: 327.6 },
                    { name: '古风权谋', value: 1, heat: 327.6 },
                    { name: '战神归来', value: 1, heat: 252.9 },
                    { name: '玄幻仙侠', value: 1, heat: 252.9 },
                    { name: '传承觉醒', value: 1, heat: 1296.1 },
                    { name: '强者回归', value: 1, heat: 792.3 },
                    { name: '大女主', value: 2, heat: 272.3 }
                ],
                monthly: [
                    { name: '逆袭', value: 20, heat: 4273.7 },
                    { name: '都市日常', value: 15, heat: 4273.7 },
                    { name: '现代言情', value: 12, heat: 2697.1 },
                    { name: '虐恋', value: 6, heat: 2697.1 },
                    { name: '打脸虐渣', value: 5, heat: 1930.4 },
                    { name: '古装', value: 4, heat: 2697.1 },
                    { name: '重生', value: 2, heat: 2697.1 },
                    { name: '民国', value: 3, heat: 2091.3 },
                    { name: '穿越', value: 3, heat: 2091.3 },
                    { name: '家庭伦理', value: 6, heat: 2091.3 },
                    { name: '奇幻爱情', value: 3, heat: 1930.4 },
                    { name: '职场', value: 3, heat: 1886.7 },
                    { name: '女性成长', value: 4, heat: 1428.5 },
                    { name: '现言甜宠', value: 1, heat: 1428.5 },
                    { name: '亲情', value: 3, heat: 1318.5 },
                    { name: '无敌神医', value: 1, heat: 900.8 },
                    { name: '异能', value: 2, heat: 967.3 },
                    { name: '小人物', value: 1, heat: 967.3 },
                    { name: '总裁', value: 2, heat: 931.1 },
                    { name: '大女主', value: 3, heat: 931.1 },
                    { name: '都市修仙', value: 1, heat: 857.5 },
                    { name: '悬疑推理', value: 2, heat: 848.5 },
                    { name: '萌宝', value: 1, heat: 810.8 },
                    { name: '乡村', value: 1, heat: 793.7 },
                    { name: '古风言情', value: 2, heat: 793.7 },
                    { name: '银发', value: 1, heat: 916.4 },
                    { name: '传承觉醒', value: 1, heat: 900.8 }
                ]
            };

            // 平台与题材关系数据
            const platformData = {
                daily: [
                    ['河马', '现代言情', 6], ['河马', '都市日常', 8], ['河马', '逆袭', 4],
                    ['番茄', '现代言情', 3], ['番茄', '都市日常', 4], ['番茄', '逆袭', 3],
                    ['快创', '逆袭', 2], ['快创', '都市日常', 2], ['快创', '现代言情', 1],
                    ['花生', '悬疑推理', 2], ['花生', '都市日常', 2], ['花生', '总裁', 1],
                    ['麦芽', '打脸虐渣', 1], ['麦芽', '都市日常', 2], ['麦芽', '亲情', 1],
                    ['山海', '逆袭', 2], ['山海', '家庭伦理', 1], ['山海', '现代言情', 1],
                    ['掌玩', '都市日常', 1], ['掌玩', '现代言情', 1],
                    ['九州', '古装', 1], ['九州', '逆袭', 1], ['九州', '职场', 1],
                    ['天桥', '现代言情', 1], ['天桥', '家庭伦理', 1], ['天桥', '萌宝', 1]
                ],
                weekly: [
                    ['河马', '逆袭', 4], ['河马', '现代言情', 5], ['河马', '奇幻爱情', 2],
                    ['麦芽', '打脸虐渣', 2], ['麦芽', '逆袭', 2], ['麦芽', '奇幻爱情', 1],
                    ['番茄', '职场', 1], ['番茄', '逆袭', 2], ['番茄', '女性成长', 1],
                    ['花生', '悬疑推理', 3], ['花生', '都市日常', 3], ['花生', '总裁', 1],
                    ['九州', '打脸虐渣', 1], ['九州', '亲情', 1], ['九州', '现代言情', 2],
                    ['快创', '战神归来', 1], ['快创', '玄幻仙侠', 1],
                    ['掌阅', '逆袭', 1], ['掌阅', '都市日常', 1]
                ],
                monthly: [
                    ['河马', '逆袭', 6], ['河马', '现代言情', 5], ['河马', '虐恋', 3],
                    ['快创', '古装', 2], ['快创', '重生', 1], ['快创', '民国', 1],
                    ['麦芽', '虐恋', 2], ['麦芽', '逆袭', 2], ['麦芽', '奇幻爱情', 1],
                    ['番茄', '逆袭', 5], ['番茄', '现代言情', 3], ['番茄', '女性成长', 2],
                    ['山海', '亲情', 1], ['山海', '家庭伦理', 1], ['山海', '逆袭', 1],
                    ['花生', '职场', 1], ['花生', '逆袭', 1], ['花生', '打脸虐渣', 1],
                    ['九州', '逆袭', 1], ['九州', '现代言情', 1]
                ]
            };

            // 合并全部数据
            if (dataType === 'all') {
                const allWordData = {};
                const allPlatformData = {};

                // 合并词云数据
                ['daily', 'weekly', 'monthly'].forEach(type => {
                    allData[type].forEach(item => {
                        if (!allWordData[item.name]) {
                            allWordData[item.name] = { ...item };
                        } else {
                            allWordData[item.name].value += item.value;
                            allWordData[item.name].heat = Math.max(allWordData[item.name].heat, item.heat);
                        }
                    });
                });

                // 合并平台数据
                ['daily', 'weekly', 'monthly'].forEach(type => {
                    platformData[type].forEach(item => {
                        const key = `${item[0]}-${item[1]}`;
                        if (!allPlatformData[key]) {
                            allPlatformData[key] = [...item];
                        } else {
                            allPlatformData[key][2] += item[2];
                        }
                    });
                });

                return {
                    wordData: Object.values(allWordData),
                    platformData: Object.values(allPlatformData)
                };
            }

            return {
                wordData: allData[dataType],
                platformData: platformData[dataType]
            };
        }

        // 渲染词云图
        function renderWordCloud(data) {
            try {
                const option = {
                    title: {
                        text: '热门题材标签分布',
                        left: 'center',
                        textStyle: {
                            fontSize: 18,
                            color: '#2c3e50'
                        }
                    },
                    tooltip: {
                        formatter: function(params) {
                            return `${params.name}<br/>出现次数: ${params.value}<br/>最高热力值: ${params.data.heat}w`;
                        }
                    },
                    series: [{
                        type: 'wordCloud',
                        shape: 'circle',
                        left: 'center',
                        top: 'center',
                        width: '90%',
                        height: '90%',
                        sizeRange: [20, 80],
                        rotationRange: [-45, 90],
                        rotationStep: 45,
                        gridSize: 12,
                        drawOutOfBound: false,
                        textStyle: {
                            fontFamily: 'Microsoft YaHei, Arial, sans-serif',
                            fontWeight: 'bold',
                            color: function (params) {
                                const value = params.data.heat;
                                if (value > 1000) return '#c23531';
                                if (value > 500) return '#2f4554';
                                if (value > 200) return '#61a0a8';
                                if (value > 100) return '#91c7ae';
                                return '#d48265';
                            }
                        },
                        emphasis: {
                            focus: 'self',
                            textStyle: {
                                shadowBlur: 10,
                                shadowColor: 'rgba(0, 0, 0, 0.5)'
                            }
                        },
                        data: data
                    }]
                };

                wordCloudChart.setOption(option);
                hideError();
            } catch (error) {
                showError('词云图渲染失败: ' + error.message);
            }
        }

        // 渲染热力图
        function renderHeatMap(data) {
            try {
                // 提取唯一的平台和题材
                const platforms = [...new Set(data.map(item => item[0]))];
                const genres = [...new Set(data.map(item => item[1]))];
                
                // 创建矩阵数据
                const matrixData = [];
                platforms.forEach((platform, i) => {
                    genres.forEach((genre, j) => {
                        const item = data.find(d => d[0] === platform && d[1] === genre);
                        matrixData.push([i, j, item ? item[2] : 0]);
                    });
                });

                const option = {
                    title: {
                        text: '平台与题材关联度',
                        left: 'center',
                        textStyle: {
                            fontSize: 18,
                            color: '#2c3e50'
                        }
                    },
                    tooltip: {
                        position: 'top',
                        formatter: function(params) {
                            return `${platforms[params.data[0]]} - ${genres[params.data[1]]}<br/>关联次数: ${params.data[2]}`;
                        }
                    },
                    grid: {
                        left: '10%',
                        right: '10%',
                        bottom: '15%',
                        top: '15%'
                    },
                    xAxis: {
                        type: 'category',
                        data: platforms,
                        splitArea: {
                            show: true
                        },
                        axisLabel: {
                            rotate: 45
                        }
                    },
                    yAxis: {
                        type: 'category',
                        data: genres,
                        splitArea: {
                            show: true
                        }
                    },
                    visualMap: {
                        min: 0,
                        max: Math.max(...data.map(item => item[2])),
                        calculable: true,
                        orient: 'horizontal',
                        left: 'center',
                        bottom: '0%',
                        inRange: {
                            color: ['#e0f3f8', '#fee090', '#fc8d59', '#c23531']
                        }
                    },
                    series: [{
                        name: '平台题材关联',
                        type: 'heatmap',
                        data: matrixData,
                        label: {
                            show: true,
                            formatter: function(params) {
                                return params.data[2] > 0 ? params.data[2] : '';
                            }
                        },
                        emphasis: {
                            itemStyle: {
                                shadowBlur: 10,
                                shadowColor: 'rgba(0, 0, 0, 0.5)'
                            }
                        }
                    }]
                };

                heatMapChart.setOption(option);
            } catch (error) {
                showError('热力图渲染失败: ' + error.message);
            }
        }

        // 初始化图表
        function initCharts(dataType = 'all') {
            if (!checkDependencies()) return;
            
            try {
                const { wordData, platformData } = processData(dataType);
                renderWordCloud(wordData);
                renderHeatMap(platformData);
            } catch (error) {
                showError('数据处理失败: ' + error.message);
            }
        }

        // 绑定控制按钮事件
        document.querySelectorAll('.control-btn').forEach(btn => {
            btn.addEventListener('click', function() {
                document.querySelectorAll('.control-btn').forEach(b => b.classList.remove('active'));
                this.classList.add('active');
                initCharts(this.dataset.type);
            });
        });

        // 页面加载时初始化
        window.addEventListener('load', function() {
            initCharts();
            
            // 响应窗口大小变化
            window.addEventListener('resize', function() {
                wordCloudChart.resize();
                heatMapChart.resize();
            });
        });
    </script>
</body>
</html>